﻿#region License
/*
Copyright (c) 2009, Open University of the Netherlands
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided 
that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the 
  following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
  the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of Open University of the Netherlands nor the names of its contributors may be 
  used to endorse or promote products derived from this software without specific prior written 
  permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/
#endregion

namespace EwbDesigner.NET
{
    using System;
    using System.Collections;
    using XmlTreeNode = System.Collections.Generic.SimpleTreeNode<EwbDesigner.NET.XmlCacheItem>;
    using XsdTreeNode = System.Collections.Generic.SimpleTreeNode<EwbDesigner.NET.XsdCacheItem>;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Windows.Forms;
    using System.Xml;
    using System.Xml.Schema;
    using System.Globalization;

    using BrightIdeasSoftware;

    using EwbDesigner.NET.Classes;

    using WeifenLuo.WinFormsUI.Docking;
    using System.Collections.Generic;
    using System.Collections.Specialized;

    public partial class XsdForm : DockContent
    {
        #region Fields

        static readonly XsdForm _instance = new XsdForm();

        private static String ListSeparator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;

        #endregion Fields

        #region Constructors

        private XsdForm()
        {
            InitializeComponent();

            HideOnClose = true;
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Collection wraps the Objects of the ObjectListView.
        /// </summary>
        public static System.Collections.IEnumerable Collection
        {
            set
            {
                Structure.ClearObjects();// SetObjects(null);
                Structure.SetObjects(((XsdTreeModel)value).Children);
                //Instance.ProcessModel(value);
            }
        }

        private void ProcessModel(IEnumerable value)
        {
        }

        /// <summary>
        /// Singleton Instance.
        /// Visible when reflecting.
        /// </summary>
        public static XsdForm Instance
        {
            get { return _instance; }
        }

        public static TreeListView Structure
        {
            get { return Instance.treeListView1; }
        }

        #endregion Properties

        #region Event Handlers

        private void StructureForm_DockStateChanged(object sender, EventArgs e)
        {
            if (DockState == DockState.Unknown)
            {
                Blank();
            }
        }

        private void TreeForm_Load(object sender, EventArgs e)
        {
            /////////////////////////
#if DEBUG
            if (this.MdiParent != null)
            {
                Debug.WriteLine("MdiParent Present");
            }
            else
            {
                Debug.WriteLine("MdiParent Missing");
            }
#endif

            ModelDelegates();

            treeListView1.ExpandAll();
        }

        private void treeListView1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '*')
            {
                treeListView1.ExpandAll();
            }
        }

        #endregion Event Handlers

        #region Methods

        private void Blank()
        {
            //if (!Structure.IsDisposed)
            //{
            //    Structure.SetObjects(null);
            //}
        }

        private void ModelDelegates()
        {
            /////////////////////////

            // Can the given object be expanded?
            Structure.CanExpandGetter = delegate(Object x)
            {
                return x is XsdTreeNode;
            };

            // What objects should belong underneath the given model object?
            Structure.ChildrenGetter = delegate(Object x)
            {
                if (x is XsdTreeNode)
                {
                    ArrayList children = new ArrayList(((XsdTreeNode)x).Children);

                    children.AddRange(((XsdTreeNode)x).Value.attributes);

                    return children;
                }

                throw new ArgumentException("Should be XsdTreeNode");
            };

            /////////////////////////
            //0: Title
            /////////////////////////

            olvColumn1.AspectGetter = delegate(object x)
            {
                return x;
            };

            olvColumn1.AspectToStringConverter = delegate(object x)
            {
                if (x is XsdTreeNode)
                {
                    return String.Format("<{0}>", ((XsdTreeNode)x).Value.name);
                }
                else if (x is KeyValuePair<String, XsdAttributeItem>)
                {
                    return String.Format("{0}", ((KeyValuePair<String, XsdAttributeItem>)x).Key);
                }
                else
                {
                    return x.GetType().Name;
                }
            };

            /////////////////////////
            //1: Value
            /////////////////////////

            olvColumn2.AspectGetter = delegate(object x)
            {
                return x;
            };

            olvColumn2.AspectToStringConverter = delegate(object x)
            {
                if (x is KeyValuePair<String, XsdAttributeItem>)
                {
                    if (!String.IsNullOrEmpty(((KeyValuePair<String, XsdAttributeItem>)x).Value.value))
                    {
                        return String.Format("= \"{0}\"", ((KeyValuePair<String, XsdAttributeItem>)x).Value.value);
                    }
                }
                else if (x is XsdTreeNode)
                {
                    XsdCacheItem xsd = ((XsdTreeNode)x).Value;

                    //Max=-1 gives infinity.
                    if (xsd.max == Decimal.MaxValue)
                    {
                        return String.Format("{0}..{1}", xsd.min.ToString(), " ∞ ");
                    }
                    else if (xsd.min == xsd.max)
                    {
                        return String.Format("{0}", xsd.min.ToString());
                    }
                    else
                    {
                        return String.Format("{0}..{1}", xsd.min.ToString(), xsd.max.ToString());
                    }
                }

                return "";
            };

            //};

            /////////////////////////
            //2: Fixed
            /////////////////////////

            olvColumn6.AspectGetter = delegate(object x)
            {
                return x;
            };

            olvColumn6.AspectGetter = delegate(object x)
            {
                if (x is KeyValuePair<String, XsdAttributeItem>)
                {
                    return !String.IsNullOrEmpty(((KeyValuePair<String, XsdAttributeItem>)x).Value.annotation);
                }
                else if (x is XsdTreeNode)
                {
                    return !String.IsNullOrEmpty(((XsdTreeNode)x).Value.annotation);
                }
                else
                {
                    return false;
                }
            };

            /////////////////////////
            //3: Optional
            /////////////////////////

            //olvColumn4.AspectGetter = delegate(object x)
            //{
            //    return x;
            //};

            //olvColumn4.AspectGetter = delegate(object x)
            //{
            //    if (x is XsdTreeNode)
            //    {

            //        switch (((XsdTreeNode)x).Value.min == 0)
            //        {
            //            case
            //            true: return true;
            //            default:
            //                return false;
            //        }
            //    }
            //    else
            //    {
            //        return CheckState.Indeterminate;
            //    }
            //};

            /////////////////////////
            //3: Type/Editor
            /////////////////////////

            //olvColumn4.AspectGetter = delegate(object x)
            //{
            //    return x;
            //};

            //olvColumn4.AspectGetter = delegate(object x)
            //{
            //    if (x is XsdTreeNode)
            //    {
            //        return ((XsdTreeNode)x).Value.e
            //    }
            //};

            /////////////////////////
            //2: Opmerkingen
            /////////////////////////

            olvColumn5.AspectGetter = delegate(object x)
            {
                return x;
            };

            olvColumn5.AspectToStringConverter = delegate(object x)
            {
                String Result = "";

                if (x is KeyValuePair<String, XsdAttributeItem>)
                {
                    if (((KeyValuePair<String, XsdAttributeItem>)x).Value.IsFlagSet(XsdAttributeFlags.FixedValue))
                    {
                        Result += "Vast ";
                    }

                    if (((KeyValuePair<String, XsdAttributeItem>)x).Value.values.Count != 0)
                    {
                        Result += "Enumeratie ";
                    }

                    //TODO
                    //if (x is KeyValuePair<String, XsdAttributeItem> && !String.IsNullOrEmpty(((((KeyValuePair<String, XsdAttributeItem>)x).Value.annotation))
                    //{
                    //    Result += "Annotatie ";
                    //}
                }
                /////////////////////////

                if (x is XsdTreeNode)
                {
                    if (((XsdTreeNode)x).Value.min == 0)
                    {
                        Result += "Optioneel ";
                    }

                    if (((XsdTreeNode)x).Value.ischoice)
                    {
                        Result += "Choice ";
                    }

                    if (!String.IsNullOrEmpty(((XsdTreeNode)x).Value.annotation))
                    {
                        Result += "Annotatie ";
                    }
                }
                return Result;
            };

            /////////////////////////

        }

        #endregion Methods

    }
}